package com.xf.system.utils.listCompare;

import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author xiefengf
 *
 * 简单集合比较器，例如泛型只有Sting类型就可以用这个工具类
 *
 */
@Component
public class ListSimpleCompareUtil<T> {

    /**
     * 获取集合比较结果
     * @param currentList 当前集合 --- 入参数据
     * @param targetList 目标集合 --- 数据库数据
     * @return
     */
    public ListCompareResult<T> compare(List<T> currentList, List<T> targetList){
        List<T> deleteList = subList(currentList,targetList);
        List<T> saveList = subList(targetList,currentList);
        List<T> updateList = intersectList(currentList, targetList);
        return new ListCompareResult<T>(saveList,deleteList,updateList);
    }

    /**
     * 求List1中有的但是List2中没有的元素
     */
    private List<T> subList(List<T> list1, List<T> list2) {
        // 过滤掉list2中的null元素
        list2 = list2.parallelStream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());

        Map<T, T> tempMap = list2.parallelStream()
                .collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));

        // 过滤掉list1中在tempMap中存在的元素
        return list1.parallelStream()
                .filter(str -> !tempMap.containsKey(str)).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }


    /**
     * 求List1和List2中都有的元素
     */
    private List<T> intersectList(List<T> list1, List<T> list2){
        // 检查list1和list2是否为null
        if (list1 == null || list2 == null) {
            // 返回一个空列表
            return Collections.emptyList();
        }
        // 过滤掉list1和list2中的null元素
        list1 = list1.parallelStream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        list2 = list2.parallelStream()
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        Map<T, T> tempMap = list2.parallelStream()
                .collect(Collectors.toMap(Function.identity(), Function.identity(), (oldData, newData) -> newData));
        return list1.parallelStream()
                .filter(tempMap::containsKey).filter(Objects::nonNull)
                .collect(Collectors.toList());
    }


    /**
     * 返回类
     * @param <T>
     */
    public static class ListCompareResult<T> {

        /**
         * 新增列表
         */
        private List<T> saveList;

        /**
         * 删除列表
         */
        private List<T> deleteList;

        /**
         * 更新列表
         */
        private List<T> updateList;

        public ListCompareResult() {
        }

        public ListCompareResult(List<T> saveList, List<T> deleteList, List<T> updateList) {
            this.saveList = saveList;
            this.deleteList = deleteList;
            this.updateList = updateList;
        }

        public List<T> getSaveList() {
            return saveList;
        }

        public void setSaveList(List<T> saveList) {
            this.saveList = saveList;
        }

        public List<T> getDeleteList() {
            return deleteList;
        }

        public void setDeleteList(List<T> deleteList) {
            this.deleteList = deleteList;
        }

        public List<T> getUpdateList() {
            return updateList;
        }

        public void setUpdateList(List<T> updateList) {
            this.updateList = updateList;
        }
    }

}
